import json

import pickle
from django import http
from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connection

from apps.goods.models import SKU
from utils.response_code import RETCODE
from utils.superjiajiemi import jiajiemiSuper

# 添加 展示 修改 删除 购物车
class CartView(View):

    #接收添加购物车的商品信息,用户登录写入redis,未登录写入cookie
    def post(self,request):
        #接受参数 ,前端传入一个json json有引号
        accept_dict = json.loads(request.body.decode()) #request.body是二进制类型
        sku_id = accept_dict.get('sku_id') #获取字典中的商品id
        count = accept_dict.get('count')
        selected = accept_dict.get('selected',True) #默认是true因为前端不会传这个
        '''参数判断'''
        if not all([sku_id,count]):
            return http.HttpResponseForbidden('缺少必传参数')
        #判断商品是否存在
        try:
            sku = SKU.objects.get(id= sku_id)
        except Exception:
            return http.HttpResponseForbidden('商品不存在')

        #判断count是否是数字
        try:
            count=int(count)
        except Exception:
            return http.HttpResponseForbidden('参数count有误')
        if selected:#因为有默认值,当有传入值的时候判断是否是布尔类型
            if not isinstance(selected,bool):
                return http.HttpResponseForbidden('参数selected有误')
        '''参数判断完毕'''



        #判断用户是否登录
        if request.user.is_authenticated:
            #redis
           #数据格式：{user_id:{"sku_id":{'count':count:'selected':selected}}}
            '''还需要查找之前的数据,存在且商品相同则累加,不存在则添加'''

            client = get_redis_connection('carts')
            carts_all = client.hgetall(request.user.id) #根据用户id获取所有购物车数据
            '''取出来的都是二进制'''
            '''如果购物车数据为空,则新建'''
            if not carts_all: #sku_id:{}
                client.hset(request.user.id,sku_id,json.dumps({'count':count,'selected':selected}))
                return JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
            #如果有数据,看是否有相同数据,如果没有则新增,有则累加

            if str(sku_id).encode() in client.hkeys(request.user.id):#hkeys取出来是个列表,字符串才可以编码转码
                #累加count
                old_count = json.loads(client.hget(request.user.id,str(sku_id)).decode()).get('count')
                count += old_count
                #可以正常存入,取出来会变成二进制
                '''将修改的数据写入数据库'''
                client.hset(request.user.id,sku_id,json.dumps({'count':count,'selected':selected}))
                client.save()
            else:
                #有数据,但是没有该商品的id
                client.hset(request.user.id,sku_id,json.dumps({'count':count,'selected':selected}))
            return JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})

        #如果没有登录,则利用cookie存储,格式 ‘{sku_id:{""}}’ json
        else:
            #cookie判断是否已经有数据了
            data = request.COOKIES.get('carts')
            if data is None:#如果没有数据
                cookie_goods_dict = json.dumps({sku_id:{'count':count,'selected':selected}})
                bs64_cookie_goods_dict = jiajiemiSuper.jiami(cookie_goods_dict)
                response = JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
                response.set_cookie('carts',bs64_cookie_goods_dict, max_age=24 * 30 * 3600)
                return response
            #如果有数据,解密,因为写入的时侯需要加密
            data = jiajiemiSuper.jiemi(data)
            cookie_goods_dict = json.loads(data) #字典
            #需要判断是否有该sku_id
            if str(sku_id) in cookie_goods_dict:
                #取出count ,累加
                old_count = cookie_goods_dict[str(sku_id)]['count']
                count += old_count
                #改完写入,加密
                cookie_goods_dict[sku_id] ={'count':count,'selected':selected}
                cookie_goods_dict = json.dumps(cookie_goods_dict)
                bs64_cookie_goods_dict = jiajiemiSuper.jiami(cookie_goods_dict)
                response = JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
                response.set_cookie('carts',bs64_cookie_goods_dict, max_age=24 * 30 * 3600)
                return response
            else:
                # 有数据但没有该sku 商品信息
                cookie_goods_dict[sku_id] = {'count': count, 'selected': selected}
                print('这里写入的是%s类型'%cookie_goods_dict)
                bs64_cookie_goods_dict = jiajiemiSuper.jiami(json.dumps(cookie_goods_dict))
                response = JsonResponse({'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
                response.set_cookie('carts', bs64_cookie_goods_dict, max_age=24 * 30 * 3600)
                return response

    #返回购物车页面,用户登录查询redis,未登录查询cookie
    def get(self,request):
        '''判断用户是否登录'''              #需要id,name,count,default_image_url,price,mount
        '''如果登录,查询redis'''
        cart_skus = []
        if request.user.is_authenticated:
            client = get_redis_connection('carts')
            sku_ids = client.hkeys(request.user.id)  #获得所有的sku_id
            print(sku_ids)
            if sku_ids is None:
                return render(request, 'cart.html')

            for sku_id in sku_ids:
                if sku_id.decode() != 'None':
                    sku_id = int(sku_id.decode()) # !这里int取消
                    #通过sku_id获取SKU商品对象
                    sku = SKU.objects.get(id=sku_id)

                    cart_skus.append({
                        'id':sku.id,
                        'name':sku.name,
                        'selected':str(json.loads(client.hget(request.user.id,str(sku_id)).decode()).get('selected')),
                        'count':str(json.loads(client.hget(request.user.id,str(sku_id)).decode()).get('count')),
                        'default_image_url':sku.default_image.url,
                        'price':str(sku.price),
                        'amount':str(json.loads(client.hget(request.user.id,str(sku_id)).decode()).get('count') * sku.price)
                    })

        # '''如果未登录,从cookie中读取'''
        else:
            data = request.COOKIES.get('carts')
            if not data:
                print('没有数据')
                return render(request,'cart.html')
            #获得 解密
            cookie_dicts = json.loads(jiajiemiSuper.jiemi(data))
            for sku_id, values in cookie_dicts.items():
                sku =SKU.objects.get(id=sku_id)
                cart_skus.append({
                    'id': sku.id,
                    'name': sku.name,
                    'selected':str(values.get('selected')),#把True转成'True'方便Json解析
                    'count':values.get('count'),
                    'default_image_url': sku.default_image.url,
                    'price': str(sku.price),  #会从Decimal中取出数字
                    'amount': str(values.get('count') * sku.price)
                })



        context ={
            'cart_skus':cart_skus
        }
        return render(request,'cart.html',context)

    #修改购物车商品信息,用户登录修改redis,未登录修改cookie
    def put(self,request):
        # 从request.body里面可以获得用户需要修改的sku_id
        accept_dict = json.loads((request.body).decode())
        sku_id = accept_dict.get('sku_id') #int类型,值不会变成字符串 只有字典的key jsonload会转换
        count = accept_dict.get('count')
        selected = accept_dict.get('selected', True)
        sku = SKU.objects.get(id=sku_id)
        try:
            count = int(count)
        except Exception:
            return http.HttpResponseForbidden('参数count有误')
        #因为修改完返回的数据不变：

        # 判断是否登录
        if request.user.is_authenticated:
            '''如果用户登录了'''  #redis

            '''连接redis服务器,并获取所有的keys即sku_id'''
            client = get_redis_connection('carts')
            #列表不会变字节....
            keys_list = client.hkeys(request.user.id)
            if str(sku_id).encode() in keys_list:
                #直接覆盖
                '''写入数据库'''
                client.hset(request.user.id,sku_id,json.dumps({'count':count,'selected':selected}))
                client.save()
                cart_sku = {
                    'id': sku_id,
                    'count': count,
                    'selected': selected,
                    'name': sku.name,
                    'default_image_url': sku.default_image.url,
                    'price': sku.price,
                    'amount': str(sku.price * count),
                }
                response = JsonResponse({'code': RETCODE.OK, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})
                return response
        else:  # 格式{sku_id:{}}
            '''用户未登录则修改cookie'''
            data = request.COOKIES.get('carts')

            #字符串进去加密,字符串出来
            #解密出来是字符串？？
            data = jiajiemiSuper.jiemi(data)
            cookie_dict =json.loads(data)
            #修改字典
            cookie_dict[sku_id]={'count':count,'selected':selected}
            scret_cookie = jiajiemiSuper.jiami(json.dumps(cookie_dict))
            cart_sku = {
                'id': sku_id,
                'count': count,
                'selected': selected,
                'name': sku.name,
                'default_image_url': sku.default_image.url,
                'price': sku.price,
                'amount': str(sku.price * count),
            }
            response = JsonResponse({'code': RETCODE.OK, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})
            response.set_cookie('carts',scret_cookie,max_age=24 * 30 * 3600)
            return response

    #删除购物车商品信息,用户登录修改redis,未登录修改cookie
    def delete(self,request):
        #接受参数sku_id
        sku_id_int = json.loads(request.body.decode()).get('sku_id')

        #判断是否登录
        '''1.如果登录,redis'''
        if request.user.is_authenticated:
            client = get_redis_connection('carts')
            client.hdel(request.user.id,sku_id_int)  #整数可以搜
            client.save()
            return JsonResponse({'code': RETCODE.OK, 'errmsg': '删除购物车成功'})

        # '''如果未登录,cookie'''
        else:
            data = request.COOKIES.get('carts')
            cookie_dict = json.loads(jiajiemiSuper.jiemi(data))
            del cookie_dict[str(sku_id_int)]
            #加密
            scret_cookie_dict_str = jiajiemiSuper.jiami(json.dumps(cookie_dict))
            response = JsonResponse({'code': RETCODE.OK, 'errmsg': '删除购物车成功'})
            response.set_cookie('carts',scret_cookie_dict_str,max_age=24 * 30 * 3600)
            return response

#全选
class CartSelectedALL(View):

    def put(self,request):
        sku_id_int = json.loads(request.body.decode()).get('sku_id')
        #可以多加入一个select进行全选或者全不选

        #判断是否登录
        if request.user.is_authenticated:
            client = get_redis_connection('carts')
            values_list = client.hvals(request.user.id)
            i = 0
            while i<len(values_list):
                values_dict = json.loads(values_list[i].decode())
                values_dict['selected'] = True
                client.hset(request.user.id,str(sku_id_int),json.dumps(values_dict))
                client.save()
                i+=1
            return JsonResponse({'code': RETCODE.OK, 'errmsg': '全选购物车成功'})
            # for values_dict in values_list:

